package com.ruoyi.cs.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.exceptions.ClientException;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.cs.domain.*;
import com.ruoyi.cs.mapper.*;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.cs.service.ITRechargeCardOperationService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 充值卡录入Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-08-27
 */
@Service
@SuppressWarnings("ALL")
public class TRechargeCardOperationServiceImpl implements ITRechargeCardOperationService 
{
    private static final Logger log = LoggerFactory.getLogger(TRechargeCardOperationServiceImpl.class);
    @Autowired
    private TRechargeCardOperationMapper tRechargeCardOperationMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private TRechargeCardMapper tRechargeCardMapper;
    @Autowired
    private TUserMapper tUserMapper;
    @Autowired
    private TRechargeMapper tRechargeMapper;
    @Autowired
    private TUserSyMapper tUserSyMapper;

    /**
     * 查询充值卡录入
     * 
     * @param recordId 充值卡录入ID
     * @return 充值卡录入
     */
    @Override
    public TRechargeCardOperation selectTRechargeCardOperationById(String recordId)
    {
        return tRechargeCardOperationMapper.selectTRechargeCardOperationById(recordId);
    }

    /**
     * 查询生成充值码列表
     * 
     * @param tRechargeCardOperation 充值卡录入
     * @return 充值卡录入
     */
    @Override
    public List<TRechargeCardOperation> selectTRechargeCardOperationList(TRechargeCardOperation tRechargeCardOperation)
    {
        return tRechargeCardOperationMapper.selectTRechargeCardOperationList(tRechargeCardOperation);
    }

    /**
     * 新增充值卡录入
     * 
     * @param tRechargeCardOperation 充值卡录入
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult insertTRechargeCardOperation(TRechargeCardOperation tRechargeCardOperation)
    {
        if (StringUtils.isEmpty(tRechargeCardOperation.getCode())) {
            return new AjaxResult (Constants.FAILCODE,"验证码不能为空！");
        }
        //短信验证码前缀
        String key = Constants.CARDPHONE_CODE+Constants.CARDPHONE;
        //从Redis获取短信验证码
        String code1 = redisCache.getCacheObject(key);
        if (StringUtils.isEmpty(code1)) {
            return new AjaxResult(Constants.FAILCODE,"验证码超时!");
        }
        if (!code1.equals(tRechargeCardOperation.getCode())) {
            return new AjaxResult(Constants.FAILCODE,"验证码错误!");
        }
        if (StringUtils.isNull(tRechargeCardOperation.getInputNum()) || StringUtils.isNull(tRechargeCardOperation.getSingleFee())
                || tRechargeCardOperation.getInputNum() < 1 || tRechargeCardOperation.getSingleFee().compareTo(new BigDecimal(0)) <= 0 ){
            return new AjaxResult(Constants.FAILCODE,"单张金额、生成张数不能为空且大于0!");
        }

        String record_id = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,8);
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        String address = AddressUtils.getRealAddressByIP(ip);

        tRechargeCardOperation.setRecordId(record_id);
        tRechargeCardOperation.setIp(ip);
        tRechargeCardOperation.setAddress(address);
        tRechargeCardOperation.setTotalFee(tRechargeCardOperation.getSingleFee().multiply(BigDecimal.valueOf(tRechargeCardOperation.getInputNum())));
        tRechargeCardOperation.setCreateTime(DateUtils.getNowDate());
        tRechargeCardOperation.setCreateBy(SecurityUtils.getUsername());
        tRechargeCardOperationMapper.insertTRechargeCardOperation(tRechargeCardOperation);

        List<TRechargeCard> list = new ArrayList<>();
        for (int i=0;i<tRechargeCardOperation.getInputNum();i++){
            TRechargeCard tt = new TRechargeCard();
            tt.setRecordId(record_id);
            tt.setSingleFee(tRechargeCardOperation.getSingleFee());
            tt.setCardPassword(IdUtils.fastUUID());
            tt.setCardStatus(Constants.CARDSTATUS0);
            tt.setCreateTime(DateUtils.getNowDate());
            tt.setRemark6(tRechargeCardOperation.getRemark6());
            tt.setCreateBy(SecurityUtils.getUsername());
            list.add(tt);
        }
        tRechargeCardMapper.batchAddCard(list);
        return AjaxResult.success();
    }

    /**
     * 修改充值卡录入
     * 
     * @param tRechargeCardOperation 充值卡录入
     * @return 结果
     */
    @Override
    public int updateTRechargeCardOperation(TRechargeCardOperation tRechargeCardOperation)
    {
        tRechargeCardOperation.setUpdateTime(DateUtils.getNowDate());
        return tRechargeCardOperationMapper.updateTRechargeCardOperation(tRechargeCardOperation);
    }

    /**
     * 批量删除充值卡录入
     * 
     * @param recordIds 需要删除的充值卡录入ID
     * @return 结果
     */
    @Override
    public int deleteTRechargeCardOperationByIds(String[] recordIds)
    {
        return tRechargeCardOperationMapper.deleteTRechargeCardOperationByIds(recordIds);
    }

    /**
     * 删除充值卡录入信息
     * 
     * @param recordId 充值卡录入ID
     * @return 结果
     */
    @Override
    public int deleteTRechargeCardOperationById(String recordId)
    {
        return tRechargeCardOperationMapper.deleteTRechargeCardOperationById(recordId);
    }

    @Override
    public AjaxResult sendNode(String userPhone) {
        String note =  VerifyCodeUtils.generateVerifyCode(6,"0123456789");
        /**短信发送  配置需要修改*/
        String result = null;
        try {
            Map map = SendSms.sendCode(userPhone, note);
            if(map.get("Code") != null && map.get("Code").equals(Constants.CODE_0)) {
                result = map.get("Code").toString();
            }
//            result = SendSms.sendCode(userPhone,note);
        } catch (TencentCloudSDKException e) {
            String errorCode = e.getErrorCode();
            if(errorCode.equals("InternalError.Timeout")){
                return new AjaxResult(Constants.FAILCODE,"请求下发短信超时!");
            }else if (errorCode.equals("UnauthorizedOperation.RequestIpNotInWhitelist")){
                return new AjaxResult(Constants.FAILCODE,"请求IP不在白名单中!");
            }else if(errorCode.equals("UnauthorizedOperation.SerivceSuspendDueToArrears")){
                return new AjaxResult(Constants.FAILCODE,"商戶欠费被停止服务!");
            }else if(errorCode.equals("InvalidParameterValue.IncorrectPhoneNumber")){
                return new AjaxResult(Constants.FAILCODE,"手机号格式错误!");
            }else if (errorCode.equals("LimitExceeded.DailyLimit")){
                return new AjaxResult(Constants.FAILCODE,"日下发条数超过设定的上限 !");
            }else if (errorCode.equals("LimitExceeded.PhoneNumberDailyLimit")){
                return new AjaxResult(Constants.FAILCODE,"当前手机号发送短信条数超过当日上限!");
            }else if (errorCode.equals("LimitExceeded.PhoneNumberOneHourLimit")){
                return new AjaxResult(Constants.FAILCODE,"当前手机号1小时内发送短信条数超过上限，请稍后重试!");
            }else {
                return new AjaxResult(Constants.FAILCODE,"发送短信异常!");
            }
        }
        if (result == null) {
            return  new AjaxResult(Constants.FAILCODE,"手机号码有问题!");
        }
        if (Constants.CODE_0.equals(result)) {
            String key = Constants.CARDPHONE_CODE+userPhone;
            redisCache.setCacheObject(key,note,1, TimeUnit.MINUTES);
        }else{
            log.error("返回发送短信失败信息:{}",result);
            return  new AjaxResult(Constants.FAILCODE,"手机号有误，发送短信失败，联系管理员处理!");
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult smsvarification(String code) {
        if (StringUtils.isEmpty(code)) {
            return new AjaxResult (Constants.FAILCODE,"验证码不能为空！");
        }
        //短信验证码前缀
        String key = Constants.CARDPHONE_CODE+Constants.CARDPHONE;
        //从Redis获取短信验证码
        String code1 = redisCache.getCacheObject(key);
        if (StringUtils.isEmpty(code1)) {
            return new AjaxResult(Constants.FAILCODE,"验证码超时!");
        }
        if (!code1.equals(code)) {
            return new AjaxResult(Constants.FAILCODE,"验证码错误!");
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult count(TRechargeCardOperation tRechargeCardOperation) {
        Map total = tRechargeCardOperationMapper.createCardFeeTotal();
        Map today = tRechargeCardOperationMapper.createCardFeeToday();
        Map range = tRechargeCardOperationMapper.createCardFeeTimeRange(tRechargeCardOperation);
        Map total1 = tRechargeCardMapper.userdCardFeeTotal();
        total.putAll(today);
        total.putAll(range);
        total.putAll(total1);
        return AjaxResult.success(total);
    }

    @Override
    public AjaxResult sellCount(TRechargeCard tRechargeCard) {
        Map total = tRechargeCardMapper.sellCardFeeTotal();
        Map today = tRechargeCardMapper.sellCardFeeToday();
        Map range = tRechargeCardMapper.sellCardFeeTimeRange(tRechargeCard);
        total.putAll(today);
        total.putAll(range);
        return AjaxResult.success(total);
    }

    @Override
    public List<TRechargeCard> cardInfoList(TRechargeCard tRechargeCard) {
        return tRechargeCardMapper.selectTRechargeCardListVo(tRechargeCard);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult rechargeCardPassword(String cardPassword,String userId) throws Exception {
        if (StringUtils.isEmpty(cardPassword) || StringUtils.isEmpty(userId)){
            return new AjaxResult(Constants.FAILCODE,"参数错误！");
        }
        TRechargeCard tRechargeCard = tRechargeCardMapper.getCardByPsd(cardPassword);
        if (StringUtils.isNull(tRechargeCard)){
            return new AjaxResult(Constants.FAILCODE,"此卡密错误！");
        }
        if (Constants.CARDSTATUS0.equals(tRechargeCard.getCardStatus())){
            return new AjaxResult(Constants.FAILCODE,"此卡密暂未出售，请联系管理员处理！");
        }
        if (!Constants.SUCCESS.equals(tRechargeCard.getDelFlag())){
            return new AjaxResult(Constants.FAILCODE,"此卡密已停用或销毁，请联系管理员处理！");
        }
        if (Constants.CARDSTATUS2.equals(tRechargeCard.getCardStatus())){
            return new AjaxResult(Constants.FAILCODE,"此卡密已使用！");
        }
        TUser tUser = tUserMapper.selectTUserById(userId);
        if (tUser == null || !Constants.SUCCESS.equals(tUser.getDelFlag())){
            return new AjaxResult(Constants.FAILCODE,"账户不存在或已被停用，请联系管理员处理！");
        }

        tUser.setUserBalance(tUser.getUserBalance().add(tRechargeCard.getSingleFee()));
        tUser.setUserTotalRecharge(tUser.getUserTotalRecharge().add(tRechargeCard.getSingleFee()));
        tUser.setUpdateTime(DateUtils.getNowDate());
        if (tUser.getUserTotalRecharge().compareTo(new BigDecimal(30)) >= 0){
            tUser.setIsBattle(Constants.ISBATTLE0);
        }

        int row = tUserMapper.updateTUserToRecharge(tUser);
        if (row == 0){
            throw new Exception("系统繁忙，请刷新重试!");
        }

        /**插入充值记录*/
        TRecharge tRecharge = new TRecharge();
        String out_trade_no = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 8);
        tRecharge.setCzId(out_trade_no);
        tRecharge.setUserId(userId);
        tRecharge.setCzMoney(tRechargeCard.getSingleFee());
        tRecharge.setCzStatus(Constants.CZSTATUS1);
        tRecharge.setCzBeforeBalance(tUser.getUserBalance());
        tRecharge.setCzAftefBalance(tUser.getUserBalance());
        tRecharge.setCzType("2");
        tRecharge.setCzSuccTime(DateUtils.getNowDate());
        /**判断是否首充*/
        BigDecimal f = tRechargeMapper.czMoneyCountByUserId(tRecharge.getUserId(),null,null);
        f = f == null ? new BigDecimal(0) : f ;
        if (f.compareTo(new BigDecimal(0)) > 0) {
            tRecharge.setFirstChargeStatus(Constants.SCSTATUS1);
        }else {
            tRecharge.setFirstChargeStatus(Constants.SCSTATUS0);
        }

        tRecharge.setPlatformOrderNo(tRechargeCard.getCardId());
        tRecharge.setUserType(tUser.getUserType());
        tRecharge.setCreateTime(DateUtils.getNowDate());
        tRecharge.setDelFlag("0");
        if (StringUtils.isNotEmpty(tUser.getUserPromotersId())){
            tRecharge.setUserPromotersId(tUser.getUserPromotersId());
        }
        int count = tRechargeMapper.insertTRecharge(tRecharge);

        /**修改充值卡信息*/
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        String address = AddressUtils.getRealAddressByIP(ip);

        tRechargeCard.setCardStatus(Constants.CARDSTATUS2);
        tRechargeCard.setUserId(userId);
        tRechargeCard.setIp(ip);
        tRechargeCard.setAddress(address);
        tRechargeCard.setCzId(out_trade_no);
        tRechargeCard.setCzTime(DateUtils.getTime());
        int row1 = tRechargeCardMapper.updateTRechargeCard(tRechargeCard);
        if (row1 == 0) {
            throw new Exception("此卡密重复操作或已停用，请联系管理员处理!");
        }

        if (StringUtils.isNotEmpty(tUser.getUserPromotersId())) {
            /**推广用户获取佣金*/
            TUser  tg = tUserMapper.selectTUserById(tUser.getUserPromotersId());
            if (tg == null){
                log.error("推广用户不存在");
            }else {
                /**获取推广用户的所有下家的充值总额*/
                String  myTgRechargeTotal= tRechargeMapper.myTgRechargeTotal(tUser.getUserPromotersId());
                Double ff  = Double.parseDouble(myTgRechargeTotal);
                BigDecimal radio = new BigDecimal(0);
                if (ff <= 1000){
                    radio = new BigDecimal(0.01).setScale(2,BigDecimal.ROUND_HALF_UP);
                }else if (1000 < ff && ff <=5000) {
                    radio = new BigDecimal(0.02).setScale(2,BigDecimal.ROUND_HALF_UP);
                }else if (5000<ff && ff <= 20000) {
                    radio = new BigDecimal(0.03).setScale(2,BigDecimal.ROUND_HALF_UP);
                }else if (20000<ff && ff<=60000) {
                    radio = new BigDecimal(0.04).setScale(2,BigDecimal.ROUND_HALF_UP);
                }else if (60000<ff && ff<=120000) {
                    radio = new BigDecimal(0.05).setScale(2,BigDecimal.ROUND_HALF_UP);
                }else if (120000<ff && ff<=500000) {
                    radio = new BigDecimal(0.06).setScale(2,BigDecimal.ROUND_HALF_UP);
                }else if (500000<ff) {
                    radio = new BigDecimal(0.08).setScale(2,BigDecimal.ROUND_HALF_UP);
                }

                BigDecimal commissionfee = tRecharge.getCzMoney().multiply(radio).setScale(2,BigDecimal.ROUND_HALF_UP);

                log.info("推广下家总金额：{},佣金比例：{}，佣金数：{}",myTgRechargeTotal,radio,commissionfee);
                tg.setUserBalance(tg.getUserBalance().add(commissionfee));
//                tg.setUserExtendBonus(tg.getUserExtendBonus().add(commissionfee));
                tg.setUpdateTime(DateUtils.getNowDate());
                int row2 = tUserMapper.updateTUserToRecharge(tg);

                if (row2 == 0) {
                    log.error("推广用户信息更新失败,请求参数:{}", JSON.toJSONString(tg));
                    //throw new SqlSessionException("推广用户信息更新失败");
                }
                /**插入用户推广收益记录表*/
                TUserSy userSy = new TUserSy();
                userSy.setUserId(tg.getUserId());
                userSy.setCzUserId(tUser.getUserId());
                userSy.setCzMoney(tRechargeCard.getSingleFee());
                userSy.setSyMoney(commissionfee);
                userSy.setCzId(out_trade_no);
                /*userSy.setActualRecharge(tRechargeCard.getSingleFee());*/
                userSy.setCreateTime(DateUtils.getNowDate());
                userSy.setCzType(tRecharge.getCzType());
                tUserSyMapper.insertTUserSy(userSy);
            }
        }

        return AjaxResult.success();
    }

    @Override
    public AjaxResult batchDestroy(String cardIds,String delFlag) {
        String[] cardIdsList= Convert.toStrArray(cardIds);
        tRechargeCardMapper.batchDestroy(cardIdsList,delFlag);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult allDestroy(String recordId) {
        tRechargeCardMapper.allDestroy(recordId);
        return AjaxResult.success();
    }
}
